package com.ums.scumspay.utils;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CounterSignUtils {
    /**
     * 加签处理
     * OPEN-BODY-SIG AppId="",Timestamp=“”,Nonce=“”,Signature=“”
     * @param appId
     * @param appKey
     * @param body
     * @return {@code String}
     * @throws Exception
     */
    public static String getOpenBodySig(String appId, String appKey, String body) throws Exception {
        //拿到对应时间格式
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        //获取一个去掉-的UUID值
        String nonce = UUIDUtil.getUUID();
        //对报文体进行加密
        byte[] data = body.getBytes("UTF-8");
        InputStream inputStream = new ByteArrayInputStream(data);
        String bodyDigest = encryptSHA256(inputStream);
        //最后对签进行组装再次加密
        String signature=appId+timestamp+nonce+bodyDigest;
        byte[] localSignature = hmacSHA256(signature.getBytes(), appKey.getBytes());
        String localSignatureStr = Base64.encodeBase64String(localSignature);
        return ("OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"");
    }

    /**
     * 加签处理
     * OPEN-BODY-SIG AppId="",Timestamp=“”,Nonce=“”,Signature=“”
     * @param appId
     * @param appKey
     * @param body
     * @return {@code String}
     * @throws Exception
     */
    public static String getOpenBodySigForNetpay(String appId, String appKey, String body) throws Exception {
        //拿到对应时间格式
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        //获取一个去掉-的UUID值
        String nonce = UUIDUtil.getUUID();
        //对报文体进行加密
        byte[] data = body.getBytes("UTF-8");
        InputStream inputStream = new ByteArrayInputStream(data);
        String bodyDigest = encryptSHA256(inputStream);
        //最后对签进行组装再次加密
        String signature=appId+timestamp+nonce+bodyDigest;
        byte[] localSignature = hmacSHA256(signature.getBytes("utf-8"), appKey.getBytes("utf-8"));
        String localSignatureStr = Base64.encodeBase64String(localSignature);
        return "?" + "authorization=" + "OPEN-FORM-PARAM" + "&appId=" + appId
                + "&timestamp=" + timestamp + "&nonce=" + nonce + "&content=" + URLEncoder.encode(body.toString(),"UTF-8")
                + "&signature=" + URLEncoder.encode(localSignatureStr,"UTF-8");
    }

    /**
     * 进行加密
     * @param is
     * @return {@code String}
     */
    private static String encryptSHA256(InputStream is) {
        try {
            return DigestUtils.sha256Hex(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param data
     * @param key
     * @return {@code byte[]}
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key, algorithm));
        return mac.doFinal(data);
    }
}
